/*!
 * @file 
 * @brief 与时间相关的方法
 */

#pragma once

/*-----------------------------------------------------------------------------
 * HEADER FILES
 *---------------------------------------------------------------------------*/
/*
 * COMMON HEADER
 */
#include <stdint.h>

/*
 * SLEEP API
 */
#ifdef _WIN32
#include <windows.h>
static inline sleep(uint32_t time_to_sleep)
{
    Sleep(time_to_sleep);
}

#elif defined __linux__
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#elif defined __APPLE__
#include <sys/time.h>
#include <unistd.h>

#endif  // SLEEP

#include "gmi_status.h"

/*-----------------------------------------------------------------------------
 * TYPE DECLARATION
 *---------------------------------------------------------------------------*/
typedef uint64_t gmi_ts_us_t;  // Microsecond
typedef uint64_t gmi_ts_ms_t;  // Millisecond
typedef uint32_t gmi_ts_s_t;   // Second

/*-----------------------------------------------------------------------------
 * DATA STRUCTURE
 *---------------------------------------------------------------------------*/

/**
 * @brief 时间配置
 */
typedef struct gmi_time_st
{
    gmi_ts_us_t timestamp_start;  ///< 起始时间
    struct timeval tv;                 ///< timeval 对象
#if defined(x86_64) || defined(arm64e)
    struct timezone tz;                ///< timezone 对象
#endif
    time_t real_time;                  ///< 整型真实时间
    char str_real_time[25];            ///< 字符型真实时间
} gmi_time_t;

/*-----------------------------------------------------------------------------
 * FUNCTIONS DECLARATION
 *---------------------------------------------------------------------------*/

/**
 * @brief time初始化
 * @return {*}
 */
gmi_time_t* gmi_time_init();

/**
 * @brief 销毁time对象
 * @param {gmi_time_t*} handle 
 * @return 非0则错误产生
 */
GMI_STATUS gmi_time_deinit(gmi_time_t* handle);

/**
 * @brief 获取实时时间
 * @param {gmi_time_t*} handle
 * @return 非0则错误产生
 */
GMI_STATUS gmi_get_real_timestamp(gmi_time_t* handle);

/**
 * @brief 获取系统时间戳
 * @param {gmi_time_t*} handle
 * @param {gmi_ts_us_t*} timestamp
 * @return 非0则错误产生
 */
GMI_STATUS gmi_get_tick(gmi_time_t* handle, gmi_ts_us_t* timestamp);

/**
 * @brief us级延迟
 * @param {gmi_time_t*} handle
 * @param {gmi_ts_us_t} time_to_sleep
 * @return 非0则错误产生
 */
GMI_STATUS gmi_sleep_us(gmi_time_t* handle,
                        gmi_ts_us_t time_to_sleep);

/**
 * @brief ms级延迟
 * @param {gmi_time_t*} handle
 * @param {gmi_ts_ms_t} time_to_sleep
 * @return 非0则错误产生
 */
GMI_STATUS gmi_sleep_ms(gmi_time_t* handle,
                        gmi_ts_ms_t time_to_sleep);

/**
 * @brief s级延迟
 * @param {gmi_time_t*} handle
 * @param {gmi_ts_s_t} time_to_sleep
 * @return 非0则错误产生
 */
GMI_STATUS gmi_sleep_s(gmi_time_t* handle, gmi_ts_s_t time_to_sleep);
